package com.rtz.util;

import org.apache.log4j.Logger;

import java.util.*;


public class MapUtil {

	private final static Logger logger = Logger.getLogger(MapUtil.class);

	public static void main(String[] args) {

		Map<String, Object> head = new HashMap<String, Object>();

		head.put("trade_code", "ACC001");
		head.put("plate_code", "WD001");
		head.put("trade_time", "20170822163600");
		head.put("nonce_str", "XHCG0001");
		head.put("trade_serial_no", "2017082216360006");
		head.put("sign", "63f009caa2ce044aba2971d27b8e81d3");
		System.err.println(head);
		Map<String, Object> verificationMap = new HashMap<>(head);
		verificationMap.remove("sign");
		System.out.println(MapUtil.mapValueToString(verificationMap));
		System.out.println(verificationMap);
		System.err.println(head);
		Map<String, Object> resMap = MapUtil.sortMapByKey(head);
		System.err.println(resMap);

		System.out.println(MapUtil.mapValueToString(resMap));
		System.out.println(
				MD5.sign(MapUtil.mapValueToString(resMap), "", "utf-8"));

	}

	/**
	 * 签名
	 * 
	 * @param verificationMap
	 * @param signStr
	 * @return
	 */
	public static String md5Sign(Map<String, Object> verificationMap,
			String key) {

		verificationMap = MapUtil.sortMapByKey(verificationMap);

		String verificationStr = MapUtil.mapValueToString(verificationMap);
		String singnStr = MD5.sign(verificationStr, key, "utf-8");
		return singnStr;
	}

	/**
	 * md5校验
	 * 
	 * @param verificationMap
	 * @param signStr
	 * @return
	 */
	public static boolean md5Verification(Map<String, Object> verificationMap,
			String signStr, String key) {

		verificationMap = MapUtil.sortMapByKey(verificationMap);

		String verificationStr = MapUtil.mapValueToString(verificationMap);

		String singnStr = MD5.sign(verificationStr, key, "utf-8");
		if (!singnStr.equals(signStr)) {
			logger.info("签名有误 " + " 待签名字符串:" + verificationStr + " 签名结果:"
					+ singnStr + "partner_sign:" + signStr);

			return false;
		} else {

			return true;

		}

	}

	/**
	 * map排序
	 * 
	 * @param map
	 * @return
	 */
	public static Map<String, Object> sortMapByKey(Map<String, Object> map) {
		if (map == null || map.isEmpty()) {
			return null;
		}

		Map<String, Object> sortMap = new TreeMap<String, Object>(
				new Comparator<String>() {
					public int compare(String obj1, String obj2) {
						// 降序排序
						return obj1.compareTo(obj2);
					}
				});
		sortMap.putAll(map);
		return sortMap;
	}
	/**
	 * 将mapValue拼接成字符串
	 * 
	 * @param map
	 * @return
	 */
	public static String mapValueToString(Map<String, Object> map) {

		StringBuilder sb = new StringBuilder();
		for (String key : map.keySet()) {
			String value = (String) map.get(key);
			sb.append(value);
		}
		return sb.toString();

	}

	/**
	 * map 是否为空或有空值
	 * 
	 * @param map
	 * @return
	 */
	public static boolean isEmpty(Map<String, Object> map) {

		if (map == null || map.isEmpty()) {

			return true;

		} else if (MapUtil.isEmptyForChild(map)) {

			return true;
		}

		return false;

	}
	/**
	 * map的子map是否为空
	 * @param map
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static boolean isEmptyForChild(Map<String, Object> map) {

		for (String key : map.keySet()) {
			Object object = map.get(key);
			if (object instanceof String) {
				if (object == null || "".equals(object)) {
					return true;
				}
			} else if (object instanceof List<?>) {
				List<Object> child = (List<Object>) object;
				if (isEmptyForChild(child)) {
					return true;
				}

			} else if (map.get(key) instanceof Map<?, ?>) {
				Map<String, Object> child = (Map<String, Object>) object;
				if (isEmptyForChild(child)) {
					return true;
				}
			} else {
				return true;
			}
		}
		return false;
	}
	/**
	 * map的子list是否为空
	 * @param list
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static boolean isEmptyForChild(List<Object> list) {

		for (Object object : list) {

			if (object instanceof String) {
				if (object == null || "".equals(object)) {
					return true;
				}
			} else if (object instanceof List<?>) {

				List<Object> child = (List<Object>) object;
				if (isEmptyForChild(child)) {
					return true;
				}

			} else if (object instanceof Map<?, ?>) {
				Map<String, Object> child = (Map<String, Object>) object;
				if (isEmptyForChild(child)) {
					return true;
				}
			} else {
				return true;
			}

		}

		return false;

	}

}
